#ifndef _DRAW_H
#define _DRAW_H

#include <stdio.h>

#include <sys/types.h>

#include <dirent.h>
#include <string.h>
#include <math.h>
#include <sys/mman.h>
#include <malloc.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

void lcd_draw_point(int *, int, int, int);
void open_lcd();
void close_fd();

void display_hanzi(int, int, char[], int, int, int);
void display_bmp(const char *, int, int, int, int, int);
void display_pic_nc(const char *, int, int, int, int, int);

int fd;
int *plcd;

short flag;
short play;

void lcd_draw_point(int *plcd, int x, int y, int color)
{
    if (x >= 0 && x < 800 && y >= 0 && y < 480)
    {
        *(plcd + 800 * y + x) = color;
    }
}

void draw_point(int x, int y, int color)
{
    open_lcd();
    lcd_draw_point(plcd, x, y, color);
    close_fd();
}

void open_lcd()
{
    if (flag == 1)
    {
        return;
    }

    fd = open("/dev/ubuntu_lcd", O_RDWR);
    plcd = mmap(NULL, 800 * 480 * 4, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    flag = 1;
}

void close_fd()
{
    if (flag == 0)
    {
        return;
    }
    munmap(plcd, 800 * 480 * 4);
    close(fd);
    flag = 0;
}

void display_hanzi(int x0, int y0, char zimo[], int w, int h, int color)
{
    int dian;
    int x, y; //像素点在屏幕的位置
    //代表点的颜色
    int xb;
    int bit;
    for (dian = 0; dian < w * h; dian++) //遍历所有的像素点  为了判断这个像素点的值是0还是1
    {
        //需要知道这个点属于那8个bit  求数组元素的下标
        int xb = dian / 8;
        //求出这个点在这8个bit位属于第几bit位
        bit = 7 - dian % 8;
        if (zimo[xb] & (1 << bit))
        {

            x = x0 + dian % w;
            y = y0 + dian / w;
            lcd_draw_point(plcd, x, y, color);
        }
    }
}

void display_pic_nc(const char *pathname, int x0, int y0, int r1, int g1, int b1)
{
    int fd1 = open(pathname, O_RDWR);

    if (-1 == fd1)
    {
        perror("open error");
        // return -1;
    }
    //读取bmp文件头的数据
    unsigned char buf[4] = {0};
    read(fd1, buf, 2);
    //判断是否是bmp图片
    if (buf[0] != 'B' || buf[1] != 'M')
    {
        printf("is not bmp\n");
    }

    int size, width, height, depth;
    read(fd1, buf, 4);
    size = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
    lseek(fd1, 0x12, SEEK_SET);
    read(fd1, buf, 4);
    width = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
    read(fd1, buf, 4);
    height = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
    lseek(fd1, 0x1c, SEEK_SET);
    read(fd1, buf, 2);
    depth = buf[1] << 8 | buf[0];
    //	printf("size=%d,width=%d,height=%d,depth=%d\n",size,width,height,depth);
    //求出bmp图片每一行的字节数=宽度*（depth/8）
    int bytes_line = fabs(width) * (depth / 8);
    //满足每行的字节数是4的倍数，如果不是，则需补充赖子
    int laizi = 0;
    if (bytes_line % 4 != 0)
    {
        laizi = 4 - bytes_line % 4;
    }
    //每一行的实际字节数
    int line = bytes_line + laizi;
    //实际开辟的空间=line*height
    int size_t = line * fabs(height);
    unsigned char *p = malloc(size_t);
    //将像素数组读取到开辟的空间中去
    lseek(fd1, 54, SEEK_SET);
    read(fd1, p, size_t);
    unsigned char a, r, g, b;
    int color;
    int i = 0;
    int x, y;
    // printf("fd %d\n",fd1);
    for (y = 0; y < fabs(height); y++)
    {
        for (x = 0; x < fabs(width); x++)
        {
            b = p[i++];
            g = p[i++];
            r = p[i++];
            if (r == r1 && g == g1 && b == b1)
            {
                continue;
            }
            if (depth == 32)
            {
                a = p[i++];
            }
            else if (depth == 24)
            {
                a = 0;
            }

            color = (a << 24) | (r << 16) | (g << 8) | b;
            lcd_draw_point(plcd, (width > 0) ? (x0 + x) : (x0 + fabs(width) - x - 1),
                           (height > 0) ? (y0 + fabs(height) - y - 1) : (y0 + y), color);
        }
        i = i + laizi; //跳过赖子
    }
    free(p);
    close(fd1);
}



//the r g b means that if these points which rgb equals r1 g1 b1 can skip in this one bmp .Do not draw this point. 
// it can draw pattern and filter the background
void display_bmp(const char *pathname, int x0, int y0, int r1, int g1, int b1)
{
    open_lcd();
    display_pic_nc(pathname, x0, y0, r1, g1, b1);
    close_fd();
}
#endif
